home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / pcutils / os2 / imshow / source / bmlib.c next >
Encoding:
C/C++ Source or Header  |  1995-12-31  |  16.4 KB  |  298 lines

  1. /******************  Module "BMLIB.C" Source Code File  ********************/
  2. /*                                                                         */
  3. /* MODULE: BMLib.c (Routines to manage bitmap files)                       */
  4. /*                                                                         */
  5. /*                                                                         */
  6. /* DEVELOPED BY:                                                           */
  7. /* -------------                                                           */
  8. /*  Martin Erzberger, 1989/93                                              */
  9. /*                                                                         */
  10. /*                                                                         */
  11. /* VERSION:                                                                */
  12. /* --------                                                                */
  13. /*  - 2.02,  1/93                                                          */
  14. /*                                                                         */
  15. /*                                                                         */
  16. /* PURPOSE OF MODULE:                                                      */
  17. /* ------------------                                                      */
  18. /*  - Some Functions to manipulate OS/2 bitmap files.                      */
  19. /*                                                                         */
  20. /***************************************************************************/
  21.  
  22.  
  23. #define INCL_GPIBITMAPS            /* Bitmap headers etc.                  */
  24. #define INCL_BITMAPFILEFORMAT      /* Bitmapfile format                    */
  25.  
  26. #include <os2.h>                   /* Main OS/2 header file                */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31.  
  32.  
  33. static ULONG  ulBytesPerLine;      /* Bytes per scanline                   */
  34. static ULONG  ulOffBits;           /* Start of image data in file          */
  35. static LONG   lMoreOffset;         /* Used with bitmap arrays              */
  36.  
  37.  
  38. /**************************  Start of bmopen  ******************************/
  39. /*                                                                         */
  40. /* BMOPEN tries to open a OS/2 bitmap file and gives bacj the handler      */
  41. /* to it. If the file can't be opened (either because it is not a bitmap   */
  42. /* or because it can't be opened at all), NULL will be given back.         */
  43. /*                                                                         */
  44. /***************************************************************************/
  45. HFILE bmopen (CHAR *szFileName, CHAR *szMode)
  46. {
  47.   HFILE   fBitmap;                               /* Filehandler            */
  48.   ULONG   ulActionTaken;                         /* Used with DosRead      */
  49.   ULONG   ulBytesRead;                           /* Used eith DosRead      */
  50.   USHORT  usType;                                /* Filetype               */
  51.  
  52.   if (!strcmp (szMode, "rb")) {                   /* Opened to read?       */
  53.     DosOpen (szFileName, &fBitmap, &ulActionTaken, 0L, 0,
  54.              OPEN_ACTION_OPEN_IF_EXISTS |
  55.              OPEN_ACTION_FAIL_IF_NEW,
  56.              OPEN_ACCESS_READONLY       |
  57.              OPEN_SHARE_DENYNONE        |
  58.              OPEN_FLAGS_NOINHERIT       |
  59.              OPEN_FLAGS_NO_CACHE        |        /* No need to cache it    */
  60.              OPEN_FLAGS_SEQUENTIAL,              /* Mostly read sequential */
  61.              0L);
  62.  
  63.     if (fBitmap == 0)                            /* Couldn't open it       */
  64.       return 0;                                  /* Give back NULL         */
  65.  
  66.     DosRead (fBitmap, &usType, sizeof (USHORT), &ulBytesRead);  /* Header  */
  67.     if (usType == BFT_BMAP) {                    /* Is it bitmap?          */
  68.       lMoreOffset = 0;                            /* See below             */
  69.       return fBitmap;                             /* Give back handler     */
  70.     } else if (usType == BFT_BITMAPARRAY) {      /* Bitmap array?          */
  71.       lMoreOffset = 14;                           /* Remove array header   */
  72.       return fBitmap;                             /* Give back handler     */
  73.     } else {
  74.       DosClose (fBitmap);                        /* No bitmap              */
  75.       return 0;                                  /* Give back NULL         */
  76.     }
  77.   } else {                                      /* Open to write           */
  78.     DosOpen (szFileName, &fBitmap, &ulActionTaken, 0L, 0,
  79.              OPEN_ACTION_OPEN_IF_EXISTS |
  80.              OPEN_ACTION_CREATE_IF_NEW,
  81.              OPEN_ACCESS_WRITEONLY      |
  82.              OPEN_SHARE_DENYWRITE       |
  83.              OPEN_FLAGS_NOINHERIT       |
  84.              OPEN_FLAGS_NO_CACHE        |   
  85.              OPEN_FLAGS_SEQUENTIAL,         
  86.              0L);
  87.  
  88.     if (fBitmap == 0)                            /* Couldn't open          */
  89.       return 0;                                  /* Give back NULL         */
  90.     else return fBitmap;                         /* Or handler             */
  91.   }
  92. }
  93. /***************************  Ende of bmopen  ******************************/
  94.  
  95.  
  96.  
  97. /**************************  Start of  bmclose  ****************************/
  98. /*                                                                         */
  99. /* bmclose closes a opened bitmap file.                                    */
  100. /* There is no return value.                                               */
  101. /*                                                                         */
  102. /***************************************************************************/
  103. VOID bmclose (HFILE fBitmap)                     /* Filehandler            */
  104. {
  105.   if (fBitmap != 0)
  106.     DosClose (fBitmap);
  107. }
  108. /*****************************  End of bmclose  ****************************/
  109.  
  110.  
  111.  
  112. /**********************  Start of procedure bmrhdr  ************************/
  113. /*                                                                         */
  114. /* Bmrhdr reads in the BITMAPINFO2 structure of an OS/2 bitmap file.       */
  115. /* In the BITMAPINFO2 structure is all the information about the file,     */
  116. /* such as size, compression etc. Also in the header is the colormap       */
  117. /* (if there is one).                                                      */
  118. /* The return value of bmrhdr is undefined.                                */
  119. /*                                                                         */
  120. /***************************************************************************/
  121. VOID  bmrhdr (HFILE hImage, PBITMAPINFO2 pbmiBitmap)
  122. {
  123.   ULONG             ulNewPointer;                   /* For DosChgFilePtr   */
  124.   ULONG             ulBytesRead;                    /* For DosRead         */
  125.   ULONG             cbFix;                          /* Header size         */
  126.   BITMAPINFOHEADER  bmpTemp;                        /* Temp. header        */
  127.   RGB               rgbTemp[256];                   /* Temp. colortable    */
  128.   USHORT            i;                              /* Loop counter        */
  129.  
  130.  /*************************************************************************/
  131.  /* The ULONG on file offset 10 states, where the actual image data       */
  132.  /* starts. This is necessary because the colormap isn't always the same  */
  133.  /* size.                                                                 */
  134.  /*************************************************************************/
  135.   DosSetFilePtr (hImage, 10+lMoreOffset, FILE_BEGIN, &ulNewPointer);
  136.   DosRead (hImage, &ulOffBits, sizeof (ULONG), &ulBytesRead);  /* ULONG   */
  137.  
  138.  /*************************************************************************/
  139.  /* At file offset 14 starts the BITMAPINFOHEADER2. The first try will be */
  140.  /* the OS/2 2.0 version of the header. With lookint at "cbFix" one can   */
  141.  /* determine if it is an OS/2 1.1 bitmap or a newer one.                 */
  142.  /*************************************************************************/
  143.   DosSetFilePtr (hImage, 14+lMoreOffset, FILE_BEGIN, &ulNewPointer);
  144.   DosRead (hImage, pbmiBitmap, sizeof (BITMAPINFOHEADER2),
  145.             &ulBytesRead);
  146.  
  147.  /*************************************************************************/
  148.  /* If it is an OS/2 1.1 bitmap ist, the header will be read in again,    */
  149.  /* this time into a BITMAPINFO. The values will then be copied field     */
  150.  /* by field into BITMAPINFO2. The colormap must also be converted        */
  151.  /* (RGB to RGB2).                                                        */
  152.  /* If it is a newer bitmap, it will also be read in again, but this      */
  153.  /* time only the first cbFix values.                                     */
  154.  /*************************************************************************/
  155.  
  156.   DosSetFilePtr (hImage, 14+lMoreOffset, FILE_BEGIN, &ulNewPointer);
  157.  
  158.   if (pbmiBitmap->cbFix == 12) {                        /* OS/2 1.1 BMP    */
  159.     memset (pbmiBitmap, 0, sizeof (BITMAPINFO2));       /* Clear header    */
  160.     DosRead (hImage, &bmpTemp, sizeof (BITMAPINFOHEADER), /* Get header    */
  161.              &ulBytesRead);
  162.     pbmiBitmap->cbFix     = bmpTemp.cbFix;          /* Copy it             */
  163.     pbmiBitmap->cx        = (ULONG)bmpTemp.cx;
  164.     pbmiBitmap->cy        = (ULONG)bmpTemp.cy;
  165.     pbmiBitmap->cPlanes   = bmpTemp.cPlanes;
  166.     pbmiBitmap->cBitCount = bmpTemp.cBitCount;
  167.     DosRead (hImage, rgbTemp, ulOffBits-26,         /* Get colormap        */
  168.               &ulBytesRead);                     
  169.     ulBytesRead = (ulBytesRead / 3);
  170.     for (i=0; i<ulBytesRead; i++) {                 /* RGB2 = 4 cytes/color*/
  171.       pbmiBitmap->argbColor[i].bBlue = rgbTemp[i].bBlue;   /* Copy it     */
  172.       pbmiBitmap->argbColor[i].bGreen = rgbTemp[i].bGreen; /* RGB =       */
  173.       pbmiBitmap->argbColor[i].bRed = rgbTemp[i].bRed;    /* 3 bytes/color*/
  174.     }
  175.   } else {                                          /* OS/2 2.0 BMP        */
  176.     cbFix = pbmiBitmap->cbFix;
  177.     memset (pbmiBitmap, 0, sizeof (BITMAPINFO2));       /* Clear header    */
  178.     DosRead (hImage, pbmiBitmap, cbFix, &ulBytesRead);  /* Get header      */
  179.     DosRead (hImage, pbmiBitmap->argbColor,           /* Get colormap      */
  180.              ulOffBits-cbFix-14-lMoreOffset, &ulBytesRead);
  181.   } /* endif */
  182.  
  183.  /*************************************************************************/
  184.  /* We need this static global variable later:                            */
  185.  /*************************************************************************/
  186.   ulBytesPerLine = ((pbmiBitmap->cBitCount * pbmiBitmap->cx + 31) / 32)
  187.                    * pbmiBitmap->cPlanes * 4;
  188.  
  189.  
  190.  /*************************************************************************/
  191.  /* At the end, set the filepointer to the start of the image data:       */
  192.  /*************************************************************************/
  193.   DosSetFilePtr (hImage, (LONG)ulOffBits, FILE_BEGIN, &ulNewPointer);
  194. }
  195. /***********************  End of procedure bmrhdr  ************************/
  196.  
  197.  
  198.  
  199. /**********************  Start of procedure bmwhdr  ************************/
  200. /*                                                                         */
  201. /* The procedure bmwhdr writes the BITMAPINFO2 into a file.                */
  202. /* The return value is undefined.                                          */
  203. /*                                                                         */
  204. /* Please note: imShow doesn't need this procedure, but I wrote also a     */
  205. /* conversion routine (IM to OS/2 BMP), which needs it.                    */
  206. /*                                                                         */
  207. /***************************************************************************/
  208. VOID  bmwhdr (HFILE hImage, PBITMAPINFOHEADER2 pbmiBitmap, RGB2 *pargbColors)
  209. {
  210.   BITMAPFILEHEADER2 bmpFile;                     /* File header            */
  211.   ULONG ulBytesWritten;                          /* For DosRead            */
  212.  
  213.   memset (&bmpFile, 0, sizeof(BITMAPFILEHEADER2));
  214.   bmpFile.usType = BFT_BMAP;                     /* Type: bitmap           */
  215.   bmpFile.xHotspot = 0;                          /* no hotspot             */
  216.   bmpFile.yHotspot = 0;
  217.  
  218.   ulBytesPerLine = ((pbmiBitmap->cBitCount * pbmiBitmap->cx + 31) / 32)
  219.                    * pbmiBitmap->cPlanes * 4;
  220.  
  221.   bmpFile.bmp2.cbFix     = pbmiBitmap->cbFix;      /* Copy header           */
  222.   bmpFile.bmp2.cx        = pbmiBitmap->cx;
  223.   bmpFile.bmp2.cy        = pbmiBitmap->cy;
  224.   bmpFile.bmp2.cPlanes   = pbmiBitmap->cPlanes;
  225.   bmpFile.bmp2.cBitCount = pbmiBitmap->cBitCount;
  226.  
  227.   if (pbmiBitmap->cBitCount == 24L)        /* No colormap?                 */
  228.     bmpFile.offBits = 54;                  /* --> Header has size 54 bits  */
  229.   else
  230.                                            /* else 54 bits plus size of    */
  231.                                            /* colormap                     */
  232.     bmpFile.offBits = 54 + (sizeof (RGB2))*(1<<(ULONG)(pbmiBitmap->cBitCount));
  233.  
  234.   ulOffBits = bmpFile.offBits;             /* Set this static variable     */
  235.  
  236.  /*************************************************************************/
  237.  /* bmpFile.cbSize is the total filesize.                                 */
  238.  /*************************************************************************/
  239.   bmpFile.cbSize = (ulBytesPerLine * pbmiBitmap->cy)
  240.                   + (ULONG)bmpFile.offBits;
  241.  
  242.   DosWrite (hImage, &bmpFile, 54, &ulBytesWritten);  /* Write header      */
  243.  
  244.   if (pbmiBitmap->cBitCount != 24L) {
  245.     DosWrite (hImage, pargbColors,                   /* Write colormap    */
  246.               (ULONG)((1<<(pbmiBitmap->cBitCount)) * sizeof (RGB2)),
  247.               &ulBytesWritten);
  248.   }
  249. }
  250. /************************  End of procedure bmwhdr  ************************/
  251.  
  252.  
  253.  
  254.  
  255. /***********************  Start of procedure bmrrows  **********************/
  256. /*                                                                         */
  257. /* Bmrrows reads in rows of an OS/2 bitmap file.                           */
  258. /* The return value is undefined.                                          */
  259. /*                                                                         */
  260. /* The static variable ulBytesPerLine is used, therefore before using      */
  261. /* bmrrows one must either call bmrhdr or bmwhdr.                          */
  262. /*                                                                         */
  263. /***************************************************************************/
  264. VOID bmrrows (HFILE hImage, BYTE *imbRowBuff, ULONG ulLine, ULONG ulNumLines)
  265. {
  266.   ULONG ulNewPointer;                               /* For DosChgFilePtr   */
  267.   ULONG ulBytesRead;                                /* For DosRead         */
  268.  
  269.   DosSetFilePtr (hImage, (LONG)(ulLine*ulBytesPerLine+ulOffBits),
  270.                  FILE_BEGIN, &ulNewPointer);
  271.   DosRead (hImage, imbRowBuff,
  272.            ulNumLines * ulBytesPerLine, &ulBytesRead);
  273. }
  274. /***********************  End of procedure bmrrows  ************************/
  275.  
  276.  
  277.  
  278. /****************************  Start of bmwrows  ***************************/
  279. /*                                                                         */
  280. /* bmwrows writes rows into an OS/2 bitmap file.                           */
  281. /* The return value is undefined.                                          */
  282. /*                                                                         */
  283. /* The static variable ulBytesPerLine is used, therefore before using      */                                                                                                                                                                                 
  284. /* bmrrows one must either call bmrhdr or bmwhdr.                          */                                                                                                                                                                                 
  285. /*                                                                         */
  286. /***************************************************************************/
  287. VOID bmwrows (HFILE hImage, BYTE *imbRowBuff, ULONG ulLine, ULONG ulNumLines)
  288. {
  289.   ULONG  ulNewPointer;                              /* For DosChgFilePtr   */
  290.   ULONG  ulBytesWritten;                            /* For DosRead         */
  291.  
  292.   DosSetFilePtr (hImage, (LONG)(ulLine*ulBytesPerLine+ulOffBits),
  293.                  FILE_BEGIN, &ulNewPointer);
  294.   DosWrite (hImage, imbRowBuff,
  295.             ulNumLines * ulBytesPerLine, &ulBytesWritten);
  296. }
  297. /****************************  End of bmwrows  *****************************/
  298.